package com.xncoding.netty.test;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.concurrent.CountDownLatch;
/**
 * <p>
 * BIO测试
 * 模拟20个客户端并发请求，服务端则使用单线程。
 */
public class SocketClient {
    public static void main(String[] args) throws InterruptedException {
        Integer clientNumber = 20;
        CountDownLatch countDownLatch = new CountDownLatch(clientNumber);
        // 分别启动20个客户端
        for (int index = 0; index < clientNumber; index++, countDownLatch.countDown()) {
            SocketClientRequestThread client = new SocketClientRequestThread(countDownLatch, index);
            new Thread(client).start();
        }
        synchronized (SocketClient.class) {
            SocketClient.class.wait();
        }
    }
}

/**
 * 客户端，用于模拟请求
 * @Author niujinpeng
 */
class SocketClientRequestThread implements Runnable {
    private CountDownLatch countDownLatch;
    /**
     * 线程的编号
     */
    private Integer clientIndex;

    public SocketClientRequestThread(CountDownLatch countDownLatch, Integer clientIndex) {
        this.countDownLatch = countDownLatch;
        this.clientIndex = clientIndex;
    }

    @Override
    public void run() {
        Socket socket = null;
        OutputStream clientRequest = null;
        InputStream clientResponse = null;
        try {
            socket = new Socket("localhost", 83);
            clientRequest = socket.getOutputStream();
            clientResponse = socket.getInputStream();
            //等待，直到SocketClientDaemon完成所有线程的启动，然后所有线程一起发送请求
            this.countDownLatch.await();
            // 发送请求信息
            clientRequest.write(("这是第" + this.clientIndex + "个客户端的请求over").getBytes());
            clientRequest.flush();
            // 等待服务器返回消息
            System.out.println("第" + this.clientIndex + "个客户端请求发送完成，等待服务器响应");
            int maxLen = 1024;
            byte[] contentBytes = new byte[maxLen];
            int realLen;
            String message = "";
            // 等待服务端返回，in和out不能cloese
            while ((realLen = clientResponse.read(contentBytes, 0, maxLen)) != -1) {
                message += new String(contentBytes, 0, realLen);
            }
            System.out.println("第" + this.clientIndex + "个客户端接受到来自服务器的消息:" + message);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            try {
                if (clientRequest != null) {
                    clientRequest.close();
                }
                if (clientRequest != null) {
                    clientResponse.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
